﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using EDXLSharp.NIEMCore;
using System.Xml;

namespace EDXLSharp.NIEMMilOpsLib
{
  /// <summary>
  /// A data type for a value from a specified controlled vocabulary.
  /// </summary>
  public abstract class CodespaceCodeType : TextType
  {
    /// <summary>
    /// A name or URI for a controlled vocabulary.
    /// </summary>
    public string CodespaceID;

    //TODO: LDY better use base type to not have redundant code.
    //should this extend TextType? or just ComplexTypeBase? -jim

    /// <summary>
    /// Writes this Object to an inline XML Document
    /// </summary>
    /// <param name="xwriter">Valid XMLWriter</param>
    /// <exception cref="System.ArgumentNullException">Thrown if xwriter is null</exception>
    /// <exception cref="EDXLSharp.ValidationException">Thrown if the object fails to validate</exception>
    public override void WriteXML(XmlWriter xwriter)
    {
      if (xwriter == null)
      {
        throw new ArgumentNullException("xwriter");
      }

      this.Validate();

      xwriter.WriteStartElement(this.ElementName, this.ElementNamespace);
      if (!String.IsNullOrWhiteSpace(this.CodespaceID))
      {
        xwriter.WriteAttributeString("codespaceID", this.CodespaceID);
      }
      xwriter.WriteString(this.Text);
      xwriter.WriteEndElement();
    }

    /// <summary>
    /// Reads this Object's values from an XML nodelist
    /// </summary>
    /// <param name="rootnode">root XML Node of the Object element</param>
    /// <exception cref="System.ArgumentNullException">Thrown if rootnode is null</exception>
    /// <exception cref="System.ArgumentException">Thrown if the rootnode is not the correct type</exception>
    /// <exception cref="EDXLSharp.ValidationException">Thrown if the object fails to validate</exception>
    public override void ReadXML(XmlNode rootnode)
    {
      if (rootnode == null)
      {
        throw new ArgumentNullException("rootnode");
      }

      if (rootnode.LocalName != this.ElementName)
      {
        throw new ArgumentException("Unexpected element " + rootnode.LocalName + " instead of " + this.ElementName);
      }

      this.Text = rootnode.InnerText;

      if (rootnode.Attributes != null)
      {
        var codespaceID = rootnode.Attributes["codespaceID"];
        if (codespaceID != null)
        {
          this.CodespaceID = codespaceID.Value;
        }
      }

      this.Validate();
    }

    /// <summary>
    /// When overridden, validates the content against applicable rules
    /// </summary>
    public override void Validate()
    {
      //TODO: LDY CodespaceCodeType validation
    }
  }
}